bitflags! {
    pub struct Cr4Flags: u64 {
        ///  Enables interrupt- and exception-handling extensions in virtual-8086 mode
        ///  when set; disables the extensions when clear. Use of the virtual mode
        ///  extensions can improve the performance of virtual-8086 applications by
        ///  eliminating the overhead of calling the virtual-8086 monitor to handle
        ///  interrupts and exceptions that occur while executing an
        ///  8086 program and, instead, redirecting the interrupts and exceptions back to
        ///       the 8086 program’s handlers. It also provides hardware support for a
        ///       virtual interrupt flag (VIF) to improve reliability of running 8086
        ///       programs in multi-tasking and multiple-processor environments.
        const VIRTUAL_8086 = 1 << 0;

        /// Enables hardware support for a virtual interrupt flag (VIF) in protected mode
        /// when set; disables the VIF flag in protected mode when clear.  See also:
        /// Section 20.4, “Protected-Mode Virtual Interrupts.”
        const PROTEDCTED_MODE_VIRTUAL_INTERRUPTS = 1 << 1;

        /// Restricts the execution of the RDTSC instruction to procedures running at
        /// privilege level 0 when set; allows RDTSC instruction to be executed at any
        /// privilege level when clear. This bit also applies to the RDTSCP instruction
        /// if supported (if CPUID.80000001H:EDX[27] = 1).
        const TIMESTAMP_DISABLE = 1 << 2;

        /// References to debug registers DR4 and DR5 cause an unde-fined opcode (#UD)
        /// exception to be generated when set; when clear, processor aliases references
        /// to regis-ters DR4 and DR5 for compatibility with software written to run on
        /// earlier IA-32 processors.
        const DEBUGGING_EXTENSIONS = 1 << 3;

        /// Enables 4-MByte pages with 32-bit paging when set; restricts 32-bit paging to
        /// pages of
        /// 4 KBytes when clear.
        const PAGE_SIZE_EXTENSIONS = 1 << 4;

        /// When set, enables paging to produce physical addresses with more than 32
        /// bits.  When clear, restricts physical addresses to 32 bits. PAE must be set
        /// before entering IA-32e mode.  See also: Chapter 4, “Paging.”
        const PHYSICAL_ADDRESS_EXTENSION = 1 << 5;

        /// Enables the machine-check exception when set; disables the machine-check
        /// exception when clear.  See also: Chapter 15, “Machine-Check Architecture.”
        const MACHINE_CHECK_ENABLE = 1 << 6;

        /// (Introduced in the P6 family processors.) Enables the global page feature
        /// when set; disables the global page feature when clear. The global page
        /// feature allows frequently used or shared pages to be marked as global to all
        /// users (done with the global flag, bit 8, in a page-direc-tory or page-table
        /// entry). Global pages are not flushed from the translation-lookaside buffer
        /// (TLB) on a task switch or a write to register CR3.When enabling the global
        /// page feature, paging must be enabled (by setting the PG flag in control
        /// register CR0) before the PGE flag is set.  Reversing this sequence may affect
        /// program correctness, and processor performance will be impacted.  See also:
        /// Section 4.10, “Caching Translation Information.”
        const PAGE_GLOBAL_ENABLE = 1 << 7;

        /// Enables execution of the RDPMC instruc-tion for programs or procedures
        /// running at any protection level when set; RDPMC instruction can be executed
        /// only at protection level 0 when clear.
        const PERFORMANCE_MONITORING_COUNTER_ENABLE = 1 << 8;

        /// When set, this flag: (1) indicates to software that the operating system
        /// supports the use of the FXSAVE and FXRSTOR instructions, (2) enables the
        /// FXSAVE and FXRSTOR instructions to save and restore the contents of the XMM
        /// and MXCSR registers along with the contents of the x87 FPU and MMX registers,
        /// and (3) enables the processor to execute SSE/SSE2/SSE3/SSSE3/SSE4
        /// instructions, with the exception of the PAUSE, PREFETCHh, SFENCE, LFENCE,
        /// MFENCE, MOVNTI, CLFLUSH, CRC32, and POPCNT.
        const OS_SUPPORT_FOR_FXSAVE_FXRSTOR = 1 << 9;

        /// When set, indicates that the operating system supports the handling of
        /// unmasked SIMD floating-point exceptions through an exception handler that is
        /// invoked when a SIMD floating-point exception (#XM) is generated. SIMD
        /// floating-point exceptions are only generated by SSE/SSE2/SSE3/SSE4.1 SIMD
        /// floating-point instructions.
        const OS_SUPPORT_FOR_UNMASKED_SIMD = 1 << 10;

        /// When set, the following instructions cannot be executed if CPL > 0: SGDT,
        /// SIDT, SLDT, SMSW, and STR. An attempt at such execution causes a
        /// general-protection exception (#GP).
        const USER_MODE_INSTRUCTION_PROTECTION = 1 << 11;

        /// Enables VMX operation when set. See Chapter 23, “Introduction to Virtual
        /// Machine Extensions.”
        const VMX_ENABLE = 1 << 13;

        /// Enables SMX operation when set. See Chapter 6, “Safer Mode Exten-sions
        /// Reference” of Intel® 64 and IA-32 Architectures Software Developer’s Manual,
        /// Volume 2D.
        const SMX_ENABLE = 1 << 14;

        /// Enables the instructions RDFSBASE, RDGSBASE, WRFSBASE, and WRGSBASE.
        const FSGSBASE_BIT = 1 << 16;

        /// Enables process-context identifiers (PCIDs) when set. See Section 4.10.1,
        /// “Process-Context Identifiers (PCIDs)”. Can be set only in IA-32e mode (if
        /// IA32_EFER.LMA = 1).
        const PCID_ENABLE_BIT = 1 << 17;

        /// When set, this flag: (1) indi-cates (via CPUID.01H:ECX.OSXSAVE[bit 27]) that
        /// the operating system supports the use of the XGETBV, XSAVE and XRSTOR
        /// instructions by general software; (2) enables the XSAVE and XRSTOR
        /// instructions to save and restore the x87 FPU state (including MMX registers),
        /// the SSE state (XMM registers and MXCSR), along with other processor extended
        /// states enabled in XCR0; (3) enables the processor to execute XGETBV and
        /// XSETBV instructions in order to read and write XCR0. See Section 2.6 and
        /// Chapter 13, “System Programming for Instruction Set Extensions and Processor
        /// Extended States”.
        const XSAVE_PROCESSOR_EXTENDED_STATES_ENABLE_BIT = 1 << 18;

        /// Enables supervisor-mode execution prevention (SMEP) when set. See Section
        /// 4.6, “Access Rights”.
        const SMEP_ENABLE_BIT = 1 << 20;

        /// Enables supervisor-mode access prevention (SMAP) when set. See Section 4.6,
        /// “Access Rights.”
        const SMAP_ENABLE_BIT = 1 << 21;

        /// Enables 4-level paging to associate each linear address with a protection
        /// key. The PKRU register specifies, for each protection key, whether user-mode
        /// linear addresses with that protection key can be read or written. This bit
        /// also enables access to the PKRU register using the RDPKRU and WRPKRU
        /// instructions.
        const PROTECTION_KEY_ENABLE_BIT = 1 << 22;
    }
}
